﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PMKB_DAL;
using KVP;
using common;
using ExceptionUtils;
using System.Text.RegularExpressions;
using System.ComponentModel.DataAnnotations;

namespace PMKB_Repository
{
   
    public class LinkAddOrEdit
    {
        public string ConnectionName;
        public I_Link link { get; set; }
        public List<KVPNew<long, string>> Tags;
        public List<long> IDSelectedTags { get; set; }
        public void LoadTags()
        {
            clsLoadTags c = new clsLoadTags();
            c.ConnectionName = ConnectionName;
            Tags = c.AllTags();
        }
        public void Delete(long id,string User)
        {
            Permission p = new Permission();
            p.ConnectionName = ConnectionName;
            if (!p.HasRightToDeleteLink(id, User))
                throw new NoPermission(User, "Link", id);

            using (Link_Tag_List lt = new Link_Tag_List(ConnectionName))
            {
                lt.Delete_LinkID(id);
                Link_List ll = new Link_List(lt);
                ll.Delete_LinkID(id);
                Link_OLAP_List ol = new Link_OLAP_List(ll);
                ol.Delete_LinkID(id);

            }
        }
        private long FindUserId(long? userid)
        {
            if (userid != null)
                return userid.Value;

            using (User_List ul = new User_List(ConnectionName))
            {
                string username = UserFind.UserName;
                var nr = ul.LoadFromDB.LoadFrom_UserNameQ(username).FirstOrDefault();
                if (nr != null)
                {
                    userid = nr.UserID;
                }
                else
                {
                    ul.Add(new User() { UserName = username });
                    ul.SaveNew();
                    userid = ul[0].UserID;
                }
            }

            return userid.Value;

        }
        internal static readonly string separator = new string((char)27, 1);
        internal static string WithSeparator(string s)
        {
            return separator + s + separator;
        }
        private void RefreshTagNames(I_Link l)
        {
            using (var tl = new Tag_List(ConnectionName))
            {
                var tags= tl.LoadFromDB.LoadFindIDsColumn_TagIDQ(IDSelectedTags).Select(item => item.TagName).ToArray();
                //esc
                var tagnames = string.Join(separator, tags);
                tagnames = WithSeparator(tagnames);
                var ll = new Link_OLAP_List(tl);
                ll.LoadFromDB.LoadFrom_LinkID(l.LinkID);
                //TODO: use AutoMapper
                ll[0].LinkDescription = l.LinkDescription;
                ll[0].LinkName= l.LinkName;
                ll[0].LinkShortURL = l.LinkShortURL;
                ll[0].LinkUrl = l.LinkUrl;
                ll[0].Tags = tagnames;

                ll.SaveExisting();
            }

        }
        public void SaveNew()
        {
            
            using (var ll = new Link_List(ConnectionName))
            {
                link.CreationUserID = FindUserId(link.CreationUserID);
                link.LinkCreationDate = DateTime.Now;
                var lnk=link as Link;
                var rez=lnk.Validate(new ValidationContext(lnk,null,null));
                if (rez.Count() == 0)
                {
                    ll.AddToExisting(this.link as Link);

                    ll.SaveExisting();
                }
                else
                {
                    //throw new ApplicationException(Utils.showerr(rez));
                    var explist = new List<Exception>();
                    foreach (var exp in rez)
                    {
                        var count = (exp.MemberNames??new List<string>()).Count();
                        if (count == 1)
                        {
                            explist.Add(new ExceptionProperty(exp.ErrorMessage,exp.MemberNames.First()));
                        }
                        else
                        {
                            explist.Add(new ExceptionBase(exp.ErrorMessage));
                        }
                        
                    }
                    throw new AggregateException(explist);

                }
            }
            Save();
        }
        public void Save()
        {
            using (Link_List ll = new Link_List(ConnectionName))
            {
                ll.LoadFromDB.LoadFrom_LinkID(link.LinkID);
                var dblink = ll[0];

                link.CreationUserID = dblink.CreationUserID;
                link.LinkCreationDate = dblink.LinkCreationDate;
                var str=link.LinkDescription ?? "";
                str = Regex.Replace(str, "<script.*?</script>", "", RegexOptions.IgnoreCase);

                link.LinkDescription = str;
                
                dblink.CopyFromItemLink(link, false);

                Link_Tag_List taglist = new Link_Tag_List(ll);
                {
                    taglist.Delete_LinkID(link.LinkID);
                    if (IDSelectedTags != null && IDSelectedTags.Count > 0)
                    {
                        foreach (var item in IDSelectedTags)
                        {
                          
                            Link_Tag lt = new Link_Tag();
                            lt.LinkID = link.LinkID;
                            lt.TagID = item;
                            taglist.AddToExisting(lt);
                        }
                        
                    }
                }
                ll.SaveExisting();
                string insert = @"INSERT INTO " + HelperTables.NameTable(Tables_PMKBEntities.Link_OLAP, PMKB_DAL.HelperTables.Separator.SqlServer) + @"
           ([LinkID]
           ,[LinkName]
           ,[LinkDescription]
           ,[LinkUrl]
           ,[CreationUserID]
           ,[LinkCreationDate]
           ,[LinkShortURL]
           ,[UserName]
           )
   select l.[LinkID]
           ,l.[LinkName]
           ,l.[LinkDescription]
           ,l.[LinkUrl]
           ,l.[CreationUserID]
           ,l.[LinkCreationDate]
           ,l.[LinkShortURL]
           ,u.[UserName]
from " + HelperTables.NameTable(Tables_PMKBEntities.Link, PMKB_DAL.HelperTables.Separator.SqlServer) + " l inner join " + HelperTables.NameTable(Tables_PMKBEntities.User, PMKB_DAL.HelperTables.Separator.SqlServer) + @" u
on l.[CreationUserID] = u.UserID
left outer join " + HelperTables.NameTable(Tables_PMKBEntities.Link_OLAP, PMKB_DAL.HelperTables.Separator.SqlServer) + @" o on l.LinkID = o.LinkID
where o.LinkID is null";
                Console.WriteLine(insert);
                ll.ExecuteCommand(insert);
            }
            RefreshTagNames(link);
        }

        public string LoadLinkName(long id)
        {
            using (Link_List ll = new Link_List(ConnectionName))
            {
                var iq=ll.LoadFromDB.LoadFrom_LinkIDQ(id);
                var data=ll.LoadFromDB.LoadFast2PropsLongString(iq,Link_List.FieldNames.LinkID, Link_List.FieldNames.LinkName);
                return data[0].Value;
            }

        }
        public I_Link LoadLink(long id)
        {
            using (Link_List ll = new Link_List(ConnectionName))
            {
                var t=ll.LoadFromDB;
                t.flaginclude = Link_FindDB.Include.Include_Link_Tag;
                t.LoadFrom_LinkID(id);
                link = ll[0];
                IDSelectedTags = (link as Link).Link_LinkID_Link_Tag_LinkID.Select(item => item.TagID).ToList();
                return link;
            }
        }
    }
}
